﻿#include <QXmlDefaultHandler>
#include <QDebug>

class VideoHandle: public QXmlDefaultHandler
{
public:
    enum {
        _unknow,
        _in_video,
        _in_actor,
        _in_summary,
    };//为什么使用枚举，因为你需要变值，根据一个变值来决定下一步的解析操作。 这也是和DOM最大的区别：SAX需要由你控制如何读取，即怎么读取它的根，它的子分支，它的孙子分支。而DOM则直接将这些事都做好，为你准备好一棵树并提供丰富的API供你调用。

    VideoHandle():m_nState(_unknow){}

    //当一个元素标记开始被解析时，调用这个函数。当对应的结束标记被解析时调用endElement()
    bool startElement(const QString &, const QString &, const QString &qName, const QXmlAttributes &atts)
    {
        switch (m_nState) {
        case _unknow:
            if (qName == QString("video")) {
                m_tags = atts.value("tag");
                m_pageURL = atts.value("page");
                m_videoName = atts.value("name");
                m_nState = _in_actor;
            }
            break;
        case _in_video:
            if (qName == QString("actor"))  m_nState = _in_actor;
            else if (qName == QString("summary")) m_nState = _in_summary;
            break;
        default:
            break;
        }
        return true;
    }

    //当一块字符数据块被解析时调用这个函数，字符数据会写到变量ch中
    bool characters(const QString &ch)
    {
        qDebug() << m_content.size() << "\t" << m_content;
        switch (m_nState) {
        case _in_actor:
        case _in_summary:
            m_content += ch;
            break;
        default:
            break;
        }
        qDebug() << m_content.size() << "\t" << m_content;
        return true;
    }

    //当一个结束的标志被解析时调用此函数。
    bool endElement(const QString & namespaceURI, const QString & localName, const QString & qName)
    {
        switch (m_nState) {
        case _in_actor:
            m_nState = _in_video;
            m_actor = m_content;
            m_content.clear();
            break;
        case _in_summary:
            m_nState = _in_video;
            m_summary = m_content;
            m_content.clear();
            break;
        case _in_video:
            m_nState = _unknow;//又一个循环
        default:
            break;
        }
        return true;
    }

    QString m_videoName;
    QString m_pageURL;
    QString m_actor;
    QString m_summary;
    QString m_tags;
protected:
    QString m_content;
    int m_nState;
};
